//
// Copyright © 2025 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//

use std::{path::Path, sync::LazyLock};

use config::FileFormat;
use secrecy::SecretString;
use serde::Deserialize;
use size::Size;

#[derive(Deserialize, Debug)]
pub struct Config {
    pub bind_port: u16,
    pub bind_host: String,

    pub token_secret: SecretString,

    pub db_connection: String,
    pub db_scheme: String,

    pub s3_bucket: String,

    // use multipart upload if blob size is greater than this
    pub multipart_threshold: Size,

    // store blobs inline if size is less than this
    pub inline_threshold: Size,

    pub cache_control: String,

    pub compact_parts_limit: usize,
    pub compact_buffer_size: usize,
}

pub mod hulyrs {
    use std::sync::LazyLock;

    pub static CONFIG: LazyLock<hulyrs::Config> = LazyLock::new(|| match hulyrs::Config::auto() {
        Ok(config) => config,
        Err(error) => {
            eprintln!("configuration error: {}", error);
            std::process::exit(1);
        }
    });
}

pub static CONFIG: LazyLock<Config> = LazyLock::new(|| {
    const DEFAULTS: &str = r#"
        bind_port = 8096
        bind_host = "0.0.0.0"

        token_secret = "secret"

        db_connection = "postgresql://root@huly.local:26257/defaultdb?sslmode=disable"
        db_scheme = "hulylake"

        s3_bucket = "hulylake"

        multipart_threshold = "4MB"
        inline_threshold = "100KB"

        cache_control = "public, no-cache"

        compact_parts_limit = 100
        compact_buffer_size = 1000
    "#;

    let mut builder =
        config::Config::builder().add_source(config::File::from_str(DEFAULTS, FileFormat::Toml));

    let path = Path::new("etc/config.toml");

    if path.exists() {
        builder = builder.add_source(config::File::with_name(path.as_os_str().to_str().unwrap()));
    }

    let settings = builder
        .add_source(config::Environment::with_prefix("HULY"))
        .build()
        .and_then(|c| c.try_deserialize::<Config>());

    match settings {
        Ok(settings) => settings,
        Err(error) => {
            eprintln!("configuration error: {}", error);
            std::process::exit(1);
        }
    }
});
